#pragma once

/* 扩展一个以时间作为日志文件切换类型的日志落地模块 
    1. 以时间进行文件滚动，实际上是以时间段进行滚动
        实现思想：time(nullptr) % gap; 
        以当前系统时间，取模时间段大小，可以得到当前时间段是第几个时间段，
        每次以当前时间取模，判断与当前文件的时间段是否一致，不一致代表不是同一个时间段
*/
#include "../logs/superlog.h"

enum class TimeGap{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAR_DAY,
};

class RollByTime : public superlog::LogSink{
    public:
        RollByTime(const std::string &basename, TimeGap gap_type):_basename(basename){
                switch(gap_type){
                    case TimeGap::GAP_SECOND: _gap_size = 1; break;
                    case TimeGap::GAP_MINUTE: _gap_size = 60; break;
                    case TimeGap::GAP_HOUR: _gap_size = 3600; break;
                    case TimeGap::GAR_DAY: _gap_size = 3600 * 24; break;
                }
                _cur_gap = _gap_size == 1 ? superlog::util::Date::now() : superlog::util::Date::now() % _gap_size; // 获取当前时间段
                std::string filename = createNewFile();
                // 1. 创建日志文件目录
                superlog::util::File::createDirectory(superlog::util::File::path(filename));
                // 2. 打开文件
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.is_open());
        }
        void log(const char *data, size_t len){
            time_t cur = superlog::util::Date::now();
            if ((cur % _gap_size) != _cur_gap) {
                _ofs.close();    // 将之前文件句柄关闭
                std::string filename = createNewFile();
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.is_open());
            }
            _ofs.write(data, len);
            assert(_ofs.good());
        }
    private:
        std::string createNewFile(){
                // 获取系统时间
                time_t t = superlog::util::Date::now();
                struct tm lt;
                localtime_r(&t, &lt);
                std::stringstream filename;
                filename << _basename;
                filename << lt.tm_year + 1900;
                filename << lt.tm_mon + 1;
                filename << lt.tm_mday;
                filename << lt.tm_hour;
                filename << lt.tm_min;
                filename << lt.tm_sec;
                filename << ".log";
                return filename.str();
            }
    private:
        std::string _basename;
        std::ofstream _ofs;
        size_t _cur_gap;        // 当前是第几个时间段
        size_t _gap_size;       // 时间段大小
};